<script setup lang="ts">
import type { Menu } from '#/api';

import { onMounted, ref } from 'vue';

import { useVbenVxeGrid } from '@vben/plugins/vxe-table';

import {
  Button,
  Card,
  message,
  Modal,
  Space,
  Switch,
  Tag,
  Tooltip,
} from 'ant-design-vue';
import {
  ChevronDown,
  ChevronRight,
  Edit,
  Plus,
  RefreshCw,
  Trash2,
} from 'lucide-vue-next';

import { deleteMenuApi, getMenuTreeApi, MenuType } from '#/api';

import MenuFormModal from './menu-form-modal.vue';

// 弹窗
const modalVisible = ref(false);
const currentMenu = ref<Menu | undefined>();
const parentMenuForAdd = ref<Menu | undefined>();

// 展开/收起状态
const isAllExpanded = ref(true);

// 使用 vxe-table
const [Grid, gridApi] = useVbenVxeGrid<Menu>({
  gridOptions: {
    data: [],
    loading: false,
    pagerConfig: {
      enabled: false, // 禁用分页
    },
    treeConfig: {
      transform: false,
      rowField: 'id',
      childrenField: 'children',
      expandAll: true,
      reserve: true,
    },
    columns: [
      {
        field: 'menuName',
        title: '菜单名称',
        minWidth: 200,
        treeNode: true,
        cellRender: {
          name: 'VxeRenderMenuName',
        },
      },
      {
        field: 'menuType',
        title: '菜单类型',
        width: 120,
        align: 'center',
        slots: { default: 'menuType' },
      },
      {
        field: 'permission',
        title: '权限标识',
        minWidth: 150,
        slots: { default: 'permission' },
      },
      {
        field: 'path',
        title: '路由地址',
        minWidth: 180,
        slots: { default: 'path' },
      },
      {
        field: 'component',
        title: '页面组件',
        minWidth: 200,
        slots: { default: 'component' },
      },
      {
        field: 'visible',
        title: '菜单状态',
        width: 120,
        align: 'center',
        slots: { default: 'visible' },
      },
      {
        field: 'action',
        title: '操作',
        width: 240,
        align: 'center',
        fixed: 'right',
        slots: { default: 'action' },
      },
    ],
  },
});

// 转换菜单类型：字符串 -> 数字
function convertMenuType(menuType: number | string): number {
  if (typeof menuType === 'number') return menuType;

  const typeMap: Record<string, number> = {
    DIRECTORY: MenuType.DIRECTORY,
    MENU: MenuType.MENU,
    BUTTON: MenuType.BUTTON,
  };

  return typeMap[menuType] || menuType;
}

// 递归转换菜单数据
function convertMenuData(menus: any[]): Menu[] {
  return menus.map((menu) => ({
    ...menu,
    menuType: convertMenuType(menu.menuType),
    children: menu.children ? convertMenuData(menu.children) : [],
  }));
}

// 保存展开状态
function saveExpandedState(): number[] {
  const $grid = gridApi.grid;
  if (!$grid) return [];

  const expandedRows = $grid.getTreeExpandRecords();
  return expandedRows.map((row: any) => row.id);
}

// 恢复展开状态
function restoreExpandedState(expandedIds: number[]) {
  const $grid = gridApi.grid;
  if (!$grid || expandedIds.length === 0) return;

  // 等待数据加载完成后恢复展开状态
  setTimeout(() => {
    const allRows = $grid.getTableData().fullData;
    expandedIds.forEach((id: number) => {
      const row = allRows.find((r: any) => r.id === id);
      if (row) {
        $grid.setTreeExpand(row, true);
      }
    });
  }, 100);
}

// 查询菜单列表（保持展开状态）
async function fetchMenuList(keepExpandedState = false) {
  // 保存当前展开状态
  const expandedIds = keepExpandedState ? saveExpandedState() : [];

  gridApi.setState({ gridOptions: { loading: true } });
  try {
    const data = await getMenuTreeApi();
    // 转换后端返回的字符串类型为数字类型
    const menuList = convertMenuData(data);
    gridApi.setState({ gridOptions: { data: menuList, loading: false } });

    // 恢复展开状态
    if (keepExpandedState) {
      restoreExpandedState(expandedIds);
    }
  } catch (error: any) {
    message.error(error?.msg);
    gridApi.setState({ gridOptions: { loading: false } });
  }
}

// 新增菜单
function handleAdd() {
  currentMenu.value = undefined;
  parentMenuForAdd.value = undefined;
  modalVisible.value = true;
}

// 新增下级菜单
function handleAddChild(record: Menu) {
  currentMenu.value = undefined;
  parentMenuForAdd.value = record;
  modalVisible.value = true;
}

// 编辑
function handleEdit(record: Menu) {
  currentMenu.value = { ...record };
  parentMenuForAdd.value = undefined;
  modalVisible.value = true;
}

// 删除
function handleDelete(record: Menu) {
  Modal.confirm({
    title: '确认删除',
    content: `确定要删除菜单"${record.menuName}"吗？`,
    onOk: async () => {
      try {
        await deleteMenuApi(record.id!);
        message.success('删除成功');
        // 删除后保持展开状态
        await fetchMenuList(true);
      } catch (error: any) {
        console.error('删除菜单失败:', error);
      }
    },
  });
}

// 切换菜单状态
async function handleStatusChange(record: Menu, checked: boolean) {
  // 这里可以调用更新菜单状态的API
  // 暂时只是演示，实际需要调用后端API
  message.info(`菜单"${record.menuName}"状态已${checked ? '启用' : '禁用'}`);
}

// 获取菜单类型标签
function getMenuTypeTag(type: number) {
  switch (type) {
    case MenuType.BUTTON: {
      return { text: '按钮', color: 'orange' };
    }
    case MenuType.DIRECTORY: {
      return { text: '目录', color: 'blue' };
    }
    case MenuType.MENU: {
      return { text: '菜单', color: 'green' };
    }
    default: {
      return { text: '未知', color: 'default' };
    }
  }
}

// 切换全部展开/收起
function toggleExpandAll() {
  const $grid = gridApi.grid;
  if (!$grid) return;

  if (isAllExpanded.value) {
    // 收起所有
    $grid.clearTreeExpand();
    isAllExpanded.value = false;
  } else {
    // 展开所有
    $grid.setAllTreeExpand(true);
    isAllExpanded.value = true;
  }
}

// 刷新
function handleRefresh() {
  fetchMenuList();
  message.success('刷新成功');
}

// 判断是否有自定义图标
onMounted(() => {
  fetchMenuList();
});
</script>

<template>
  <div class="flex h-full flex-col p-4">
    <Card :bordered="false" class="flex flex-1 flex-col overflow-hidden">
      <!-- 顶部操作栏 -->
      <div class="mb-4 flex flex-shrink-0 justify-between">
        <Space>
          <Button @click="toggleExpandAll">
            <ChevronDown v-if="isAllExpanded" :size="16" class="mr-1" />
            <ChevronRight v-else :size="16" class="mr-1" />
            {{ isAllExpanded ? '全部收起' : '全部展开' }}
          </Button>
          <Button v-permission="'sys:menu:add'" type="primary" @click="handleAdd">
            <Plus :size="16" class="mr-1" />
            新增菜单
          </Button>
        </Space>
        <Tooltip title="刷新">
          <Button @click="handleRefresh">
            <RefreshCw :size="16" />
          </Button>
        </Tooltip>
      </div>

      <!-- 树形表格 -->
      <div class="flex-1 overflow-hidden">
        <Grid class="h-full">
          <!-- 菜单类型列 -->
          <template #menuType="{ row }">
            <Tag :color="getMenuTypeTag(row.menuType).color">
              {{ getMenuTypeTag(row.menuType).text }}
            </Tag>
          </template>

          <!-- 权限标识列 -->
          <template #permission="{ row }">
            <span class="text-gray-500">{{ row.permission || '-' }}</span>
          </template>

          <!-- 路由地址列 -->
          <template #path="{ row }">
            <span class="text-blue-600">{{ row.path || '-' }}</span>
          </template>

          <!-- 页面组件列 -->
          <template #component="{ row }">
            <span class="text-sm text-gray-600">{{
              row.component || '-'
            }}</span>
          </template>

          <!-- 菜单状态列 -->
          <template #visible="{ row }">
            <Switch
              :checked="row.visible === 1"
              checked-children="显示"
              un-checked-children="隐藏"
              @change="(checked) => handleStatusChange(row, checked)"
            />
          </template>

          <!-- 操作列 -->
          <template #action="{ row }">
            <Space :size="8">
              <!-- 按钮类型不能添加子菜单 -->
              <Button
                v-if="row.menuType !== 'BUTTON' && row.menuType !== 3"
                v-permission="'sys:menu:add'"
                type="link"
                size="small"
                @click="handleAddChild(row)"
                class="p-0"
              >
                <Plus :size="14" class="mr-1" />
                新增下级
              </Button>
              <Button
                v-permission="'sys:menu:edit'"
                type="link"
                size="small"
                @click="handleEdit(row)"
                class="p-0"
              >
                <Edit :size="14" class="mr-1" />
                修改
              </Button>
              <Button
                v-permission="'sys:menu:delete'"
                type="link"
                size="small"
                danger
                @click="handleDelete(row)"
                class="p-0"
              >
                <Trash2 :size="14" class="mr-1" />
                删除
              </Button>
            </Space>
          </template>
        </Grid>
      </div>
    </Card>

    <!-- 新增/编辑弹窗 -->
    <MenuFormModal
      v-model:visible="modalVisible"
      :menu-data="currentMenu"
      :parent-menu="parentMenuForAdd"
      @success="() => fetchMenuList(true)"
    />
  </div>
</template>

<style scoped>
:deep(.ant-btn-link) {
  height: auto;
  padding: 0;
}

/* 菜单图标样式 */
.menu-icon {
  flex-shrink: 0;
  margin-right: 8px;
  color: #666;
}
</style>
